<?php

declare(strict_types=1);

namespace app\admin\service;

use think\Log;
use think\facade\Cache;
use think\Config;

/**
 * BootData第三方API对接服务类
 * 实现停车场数据中心API的完整对接功能
 */
class BootDataApiService
{
    // API配置
    private $baseUrl;
    private $appId;
    private $appSecret;
    private $timeout = 30;
    
    public function __construct()
    {
        $config = Config::get('bootdata');
        $this->baseUrl = $config['base_url'] ?? 'http://test-gateway.qcyuns.com/park-data-api/data/centre/api/v1';
        $this->appId = $config['app_id'] ?? '';
        $this->appSecret = $config['app_secret'] ?? '';
    }
    
    /**
     * 生成签名
     */
    private function generateSign($data, $timestamp)
    {
        // 按字典序排序
        ksort($data);
        $queryString = http_build_query($data);
        $signString = $queryString . '&timestamp=' . $timestamp . '&secret=' . $this->appSecret;
        return strtoupper(md5($signString));
    }
    
    /**
     * 发送HTTP请求
     */
    private function sendRequest($url, $data = [])
    {
        $timestamp = time();
        $requestData = [
            'appId' => $this->appId,
            'timestamp' => $timestamp,
            'data' => $data
        ];
        
        $sign = $this->generateSign($data, $timestamp);
        $requestData['sign'] = $sign;
        
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $this->baseUrl . $url,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => json_encode($requestData),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => $this->timeout,
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/json',
                'User-Agent: ParkSystem/1.0'
            ],
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false
        ]);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);
        
        if ($error) {
            Log::error('BootData API请求失败: ' . $error);
            return ['success' => false, 'message' => $error];
        }
        
        if ($httpCode !== 200) {
            Log::error("BootData API HTTP错误: {$httpCode}");
            return ['success' => false, 'message' => "HTTP错误: {$httpCode}"];
        }
        
        $result = json_decode($response, true);
        if (!$result) {
            Log::error('BootData API响应解析失败: ' . $response);
            return ['success' => false, 'message' => '响应解析失败'];
        }
        
        return $result;
    }
    
    // =========================== 下行接口（第三方主动调用） ===========================
    
    /**
     * 0. 获取车场信息
     */
    public function getParkInfo()
    {
        return $this->sendRequest('/park/info');
    }
    
    /**
     * 1. 获取车辆信息
     */
    public function getVehicleInfo($plateNumber, $plateColor = 1)
    {
        $data = [
            'plateNumber' => $plateNumber,
            'plateColor' => $plateColor
        ];
        return $this->sendRequest('/vehicle/info', $data);
    }
    
    /**
     * 2. 获取车辆信息v2（公众号）
     */
    public function getVehicleInfoV2($plateNumber, $plateColor = 1)
    {
        $data = [
            'plateNumber' => $plateNumber,
            'plateColor' => $plateColor
        ];
        return $this->sendRequest('/vehicle/info/v2', $data);
    }
    
    /**
     * 3. 获取车辆临停缴费信息V3
     */
    public function getVehiclePaymentInfo($plateNumber, $plateColor = 1)
    {
        $data = [
            'plateNumber' => $plateNumber,
            'plateColor' => $plateColor
        ];
        return $this->sendRequest('/vehicle/payment/info/v3', $data);
    }
    
    /**
     * 4. 获取通道信息
     */
    public function getChannelInfo()
    {
        return $this->sendRequest('/channel/info');
    }
    
    /**
     * 5. 获取车辆计费类型
     */
    public function getVehicleChargeType($plateNumber, $plateColor = 1)
    {
        $data = [
            'plateNumber' => $plateNumber,
            'plateColor' => $plateColor
        ];
        return $this->sendRequest('/vehicle/charge/type', $data);
    }
    
    /**
     * 6. 获取车位信息
     */
    public function getParkingSpaces()
    {
        return $this->sendRequest('/parking/spaces');
    }
    
    // =========================== 临停缴费相关接口 ===========================
    
    /**
     * 2.1 生成临停缴费订单
     */
    public function createPaymentOrder($plateNumber, $plateColor, $payAmount, $payMethod, $orderNo)
    {
        $data = [
            'plateNumber' => $plateNumber,
            'plateColor' => $plateColor,
            'payAmount' => $payAmount,
            'payMethod' => $payMethod,
            'orderNo' => $orderNo,
            'payTime' => date('Y-m-d H:i:s')
        ];
        return $this->sendRequest('/payment/order/create', $data);
    }
    
    /**
     * 2.2 支付后通知接口
     */
    public function paymentNotify($orderNo, $payResult, $payTime, $actualAmount)
    {
        $data = [
            'orderNo' => $orderNo,
            'payResult' => $payResult,
            'payTime' => $payTime,
            'actualAmount' => $actualAmount
        ];
        return $this->sendRequest('/payment/notify', $data);
    }
    
    // =========================== 优惠减免相关接口 ===========================
    
    /**
     * 3.1 商家减免接口
     */
    public function merchantDiscount($plateNumber, $plateColor, $discountAmount, $discountType, $reason)
    {
        $data = [
            'plateNumber' => $plateNumber,
            'plateColor' => $plateColor,
            'discountAmount' => $discountAmount,
            'discountType' => $discountType,
            'reason' => $reason,
            'operatorId' => session('admin_id'),
            'operateTime' => date('Y-m-d H:i:s')
        ];
        return $this->sendRequest('/discount/merchant', $data);
    }
    
    /**
     * 3.2 发送优惠券
     */
    public function sendCoupon($plateNumber, $plateColor, $couponType, $couponAmount, $validDays)
    {
        $data = [
            'plateNumber' => $plateNumber,
            'plateColor' => $plateColor,
            'couponType' => $couponType,
            'couponAmount' => $couponAmount,
            'validDays' => $validDays,
            'sendTime' => date('Y-m-d H:i:s')
        ];
        return $this->sendRequest('/coupon/send', $data);
    }
    
    /**
     * 3.3 查询优惠抵扣金额
     */
    public function getDiscountAmount($plateNumber, $plateColor)
    {
        $data = [
            'plateNumber' => $plateNumber,
            'plateColor' => $plateColor
        ];
        return $this->sendRequest('/discount/amount', $data);
    }
    
    /**
     * 3.4 取消商家减免
     */
    public function cancelMerchantDiscount($plateNumber, $plateColor, $discountId)
    {
        $data = [
            'plateNumber' => $plateNumber,
            'plateColor' => $plateColor,
            'discountId' => $discountId,
            'cancelReason' => '管理员取消',
            'operatorId' => session('admin_id')
        ];
        return $this->sendRequest('/discount/cancel', $data);
    }
    
    // =========================== 登记车相关接口 ===========================
    
    

    
    // =========================== 预约车相关接口 ===========================
    
    /**
     * 5.1 添加预约车
     */
    public function addReservedVehicle($plateNumber, $plateColor, $reserveTime, $ownerName, $ownerPhone)
    {
        $data = [
            'plateNumber' => $plateNumber,
            'plateColor' => $plateColor,
            'reserveTime' => $reserveTime,
            'ownerName' => $ownerName,
            'ownerPhone' => $ownerPhone,
            'operatorId' => session('admin_id'),
            'createTime' => date('Y-m-d H:i:s')
        ];
        return $this->sendRequest('/vehicle/reserve/add', $data);
    }
    
    /**
     * 5.2 删除预约车
     */
    public function deleteReservedVehicle($plateNumber, $plateColor, $reserveId)
    {
        $data = [
            'plateNumber' => $plateNumber,
            'plateColor' => $plateColor,
            'reserveId' => $reserveId,
            'operatorId' => session('admin_id')
        ];
        return $this->sendRequest('/vehicle/reserve/delete', $data);
    }
    
    // =========================== 黑名单相关接口 ===========================
    
    /**
     * 6.1 查询黑名单
     */
    public function getBlacklist($plateNumber = '', $pageNo = 1, $pageSize = 20)
    {
        $data = [
            'plateNumber' => $plateNumber,
            'pageNo' => $pageNo,
            'pageSize' => $pageSize
        ];
        return $this->sendRequest('/blacklist/query', $data);
    }
    
    /**
     * 6.2 编辑黑名单（添加，删除）
     */
    public function editBlacklist($plateNumber, $plateColor, $action, $reason = '')
    {
        $data = [
            'plateNumber' => $plateNumber,
            'plateColor' => $plateColor,
            'action' => $action, // add 或 delete
            'reason' => $reason,
            'operatorId' => session('admin_id'),
            'operateTime' => date('Y-m-d H:i:s')
        ];
        return $this->sendRequest('/blacklist/edit', $data);
    }
    
    // =========================== 相机操作接口 ===========================
    
    /**
     * 7.1 远程开闸
     */
    public function openGate($channelId, $reason = '手动开闸')
    {
        $data = [
            'channelId' => $channelId,
            'action' => 'open',
            'reason' => $reason,
            'operatorId' => session('admin_id'),
            'operateTime' => date('Y-m-d H:i:s')
        ];
        return $this->sendRequest('/gate/control', $data);
    }
    
    /**
     * 7.2 远程关闸
     */
    public function closeGate($channelId, $reason = '手动关闸')
    {
        $data = [
            'channelId' => $channelId,
            'action' => 'close',
            'reason' => $reason,
            'operatorId' => session('admin_id'),
            'operateTime' => date('Y-m-d H:i:s')
        ];
        return $this->sendRequest('/gate/control', $data);
    }
    
    // =========================== 累计费用接口 ===========================
    
    /**
     * 8.1 获取车辆累计费用信息
     */
    public function getVehicleAccumulatedFee($plateNumber, $plateColor)
    {
        $data = [
            'plateNumber' => $plateNumber,
            'plateColor' => $plateColor
        ];
        return $this->sendRequest('/vehicle/accumulated/fee', $data);
    }
    
    // =========================== 订单记录接口 ===========================
    
    /**
     * 9.1 获取车辆订单记录
     */
    public function getVehicleOrderRecords($plateNumber, $startTime, $endTime, $pageNo = 1, $pageSize = 20)
    {
        $data = [
            'plateNumber' => $plateNumber,
            'startTime' => $startTime,
            'endTime' => $endTime,
            'pageNo' => $pageNo,
            'pageSize' => $pageSize
        ];
        return $this->sendRequest('/vehicle/order/records', $data);
    }
    
    // =========================== 语音屏显接口 ===========================
    
    /**
     * 10.1 发送语音播报
     */
    public function sendVoiceBroadcast($channelId, $content, $voiceType = 1)
    {
        $data = [
            'channelId' => $channelId,
            'content' => $content,
            'voiceType' => $voiceType,
            'sendTime' => date('Y-m-d H:i:s')
        ];
        return $this->sendRequest('/voice/broadcast', $data);
    }
    
    /**
     * 10.2 发送屏显信息
     */
    public function sendScreenDisplay($channelId, $content, $displayTime = 5)
    {
        $data = [
            'channelId' => $channelId,
            'content' => $content,
            'displayTime' => $displayTime,
            'sendTime' => date('Y-m-d H:i:s')
        ];
        return $this->sendRequest('/screen/display', $data);
    }
    
    /**
     * 10.3 发送语音加屏显
     */
    public function sendVoiceAndScreen($channelId, $voiceContent, $screenContent, $displayTime = 5)
    {
        $data = [
            'channelId' => $channelId,
            'voiceContent' => $voiceContent,
            'screenContent' => $screenContent,
            'displayTime' => $displayTime,
            'sendTime' => date('Y-m-d H:i:s')
        ];
        return $this->sendRequest('/voice/screen', $data);
    }
    
    // =========================== 发票开具接口 ===========================
    
    /**
     * 12.1 停车发票开具
     */
    public function issueInvoice($orderNo, $invoiceType, $invoiceTitle, $taxNumber = '', $amount)
    {
        $data = [
            'orderNo' => $orderNo,
            'invoiceType' => $invoiceType,
            'invoiceTitle' => $invoiceTitle,
            'taxNumber' => $taxNumber,
            'amount' => $amount,
            'applyTime' => date('Y-m-d H:i:s')
        ];
        return $this->sendRequest('/invoice/issue', $data);
    }
    
    // =========================== 上行接口处理（接收推送） ===========================
    
    /**
     * 处理进出场记录推送
     */
    public function handleParkingRecord($recordData)
    {
        try {
            // 验证数据完整性
            if (!isset($recordData['plateNumber']) || !isset($recordData['recordType'])) {
                return ['success' => false, 'message' => '数据不完整'];
            }
            
            // 保存进出场记录到本地数据库
            $result = \think\Db::table('parking_records')->insert([
                'plate_number' => $recordData['plateNumber'],
                'plate_color' => $recordData['plateColor'] ?? 1,
                'record_type' => $recordData['recordType'], // 1进场 2出场
                'channel_id' => $recordData['channelId'] ?? '',
                'record_time' => $recordData['recordTime'] ?? date('Y-m-d H:i:s'),
                'image_url' => $recordData['imageUrl'] ?? '',
                'confidence' => $recordData['confidence'] ?? 0,
                'create_time' => date('Y-m-d H:i:s')
            ]);
            
            Log::info('进出场记录推送处理成功', $recordData);
            return ['success' => true, 'message' => '处理成功'];
            
        } catch (\Exception $e) {
            Log::error('进出场记录推送处理失败: ' . $e->getMessage(), $recordData);
            return ['success' => false, 'message' => $e->getMessage()];
        }
    }
    
    /**
     * 处理车辆续费推送
     */
    public function handleVehicleRenewal($renewalData)
    {
        try {
            // 验证数据完整性
            if (!isset($renewalData['plateNumber']) || !isset($renewalData['renewalAmount'])) {
                return ['success' => false, 'message' => '数据不完整'];
            }
            
            // 保存续费记录到本地数据库
            $result = \think\Db::table('renewal_records')->insert([
                'plate_number' => $renewalData['plateNumber'],
                'plate_color' => $renewalData['plateColor'] ?? 1,
                'renewal_amount' => $renewalData['renewalAmount'],
                'renewal_time' => $renewalData['renewalTime'] ?? date('Y-m-d H:i:s'),
                'renewal_months' => $renewalData['renewalMonths'] ?? 1,
                'old_expire_time' => $renewalData['oldExpireTime'] ?? '',
                'new_expire_time' => $renewalData['newExpireTime'] ?? '',
                'create_time' => date('Y-m-d H:i:s')
            ]);
            
            Log::info('车辆续费推送处理成功', $renewalData);
            return ['success' => true, 'message' => '处理成功'];
            
        } catch (\Exception $e) {
            Log::error('车辆续费推送处理失败: ' . $e->getMessage(), $renewalData);
            return ['success' => false, 'message' => $e->getMessage()];
        }
    }
} 